2

准备工作:
1、下载laravel框架
2、配置好项目(数据库连接以及虚拟主机)

开始:
前台用户认证laravel已经为我们写好了,此部分可参考官方文档

创建模型(以adminstrator为例)

php artisan make:model Models/Adminstrator -m 

编写administrator表迁移

Schema::create('administrators', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->string('login_name')->unique();
    $table->string('display_name')->nullable();
    $table->string('password');
    $table->string('avatar')->nullable();
    $table->rememberToken();
    $table->tinyInteger('status')->default(1);
    $table->timestamps();
});

编写administrator模型

<?php

namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;

class Administrator extends Model implements AuthenticatableContract
{
    use Authenticatable;

    protected $fillable = [
        'login_name', 'password'
    ];

    protected $hidden = [
        'password', 'remember_token'
    ];
}

创建后台配置文件admin.php,在return数组中写入

'auth' => [
    'guards' => [
        'administrator' => [
            'driver'   => 'session',
            'provider' => 'administrators',
        ],
    ],

    'providers' => [
        'administrators' => [
            'driver' => 'eloquent',
            'model'  => \App\Models\Administrator::class,
        ],
    ],
],

创建后台用户认证中间件Authenticate,运行:

php artisan make:middleware Admin/Authenticate

修改handle方法:

<?php

/**
 * 用户认证中间件
 */

namespace App\Http\Middleware\Admin;

use Closure;
use Illuminate\Support\Facades\Auth;
    
class Authenticate
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (Auth::guard('administrator')->guest() && !$this->shouldPassThrough($request)) {
            return redirect()->guest(admin_base_path('login'));
        }
        return $next($request);
    }

    /**
     * Determine if the request has a URI that should pass through verification.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return bool
     */
    protected function shouldPassThrough($request)
    {
        $excepts = [
            admin_base_path('login'),
            admin_base_path('logout'),
        ];
        foreach ($excepts as $except) {
            if ($except !== '/') {
                $except = trim($except, '/');
            }
            if ($request->is($except)) {
                return true;
            }
        }
        return false;
    }
}

创建AdminServiceProvider,运行:

php artisan make:provider AdminServiceProvider

编写:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AdminServiceProvider extends ServiceProvider
{
    /**
     * 路由中间件
     * @var array
     */
    protected $routeMiddleware = [
        'admin.auth' => \App\Http\Middleware\Admin\Authenticate::class,
        'admin.pjax' => \Spatie\Pjax\Middleware\FilterIfPjax::class,
        'admin.log' => \App\Http\Middleware\Admin\LogOperation::class,
    ];

    /**
     * 中间件组
     * @var array
     */
    protected $middlewareGroups = [
        'admin' => [
            'admin.auth',
            'admin.pjax',
            'admin.log',
        ],
    ];

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        if (file_exists($routes = base_path('routes/admin.php'))) {
            $this->loadRoutesFrom($routes);
        }
    }

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->loadAdminAuthConfig();

        $this->registerRouteMiddleWare();
    }

    /**
     * 注册路由中间件
     */
    public function registerRouteMiddleWare()
    {
        // 注册路由中间件
        foreach ($this->routeMiddleware as $key => $middleware) {
            app('router')->aliasMiddleware($key, $middleware);
        }

        // 注册路由中间件组
        foreach ($this->middlewareGroups as $key => $middleware) {
            app('router')->middlewareGroup($key, $middleware);
        }
    }

    /**
     * Setup auth configuration.
     *
     * @return void
     */
    protected function loadAdminAuthConfig()
    {
        config(array_dot(config('admin.auth', []), 'auth.'));
    }
}

config/app.php中注册provider和facades

'providers' => [
    ...,
    App\Providers\AdminServiceProvider::class,
]

'aliases' => [
    ...,
    'Admin' => App\Facades\Admin\Admin::class,
]

创建登录表单验证类,运行:

php artisan make:request AdministratorLoginRequest

重写其父类rulesmessages方法:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class AdministratorLoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'login_name' => 'required',
            'password' => ['required', 'min:6'] //密码必须,最小长度为6
        ];
    }

    public function messages()
    {
        return [
            'login_name.required' => '请输入用户名',
            'password.required' => '请输入密码',
            'password.min' => '密码至少6位',
        ];
    }
}

创建登录控制器,运行:

php artisan make:controller Admin/Auth/LoginController

编写登录方法:

<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Requests\AdministratorLoginRequest;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    /**
     * 登录表单
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function getLoginForm()
    {
        if (!Auth::guard('administrator')->guest()) {
            return redirect(config('admin.route.prefix'));
        }

        return view(admin_view_base_path('auth.login.index'));
    }

    /**
     * 登录操作
     * @param AdministratorLoginRequest $loginRequest
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function postLogin(AdministratorLoginRequest $loginRequest)
    {
        $postData = $loginRequest->only('login_name', 'password', 'remember');

        $result = Auth::guard('administrator')->attempt($postData, $loginRequest->filled('remember'));

        if ($result) {
            admin_toast('登录成功');
            $loginRequest->session()->regenerate();
            return redirect()->intended(config('admin.route.prefix'));
        }else{
            return redirect()->back()->withInput()
                ->withErrors([
                    'login_name' => '用户名或密码错误'
                ]);
        }
    }

    /**
     * 注销登录
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function postLogout()
    {
        Auth::guard('administrator')->logout();

        session()->forget('url.intented');

        return redirect(config('admin.route.prefix'));
    }
}

至此,认证业务已经完成,接下来进行完善,使系统能够跑起来

创建视图文件(ps:1、控制器中使用的admin_view_base_path为自定义函数,指向后台视图文件主目录。2、视图采用AdminLTE框架)
login.blade:form

<form action="{{ admin_base_path('login') }}" method="post">
            @csrf

            <div class="form-group has-feedback">
                <input type="text" class="form-control {{ $errors->has('login_name') ? ' is-invalid' : '' }}"
                       placeholder="登 录 名" name="login_name" value="{{ old('login_name') }}" required autofocus>
                <span class="glyphicon glyphicon-envelope form-control-feedback"></span>

                @if ($errors->has('login_name'))
                <span class="invalid-feedback">
                    <strong class="text-danger">{{ $errors->first('login_name') }}</strong>
                </span>
                @endif
            </div>

            <div class="form-group has-feedback">
                <input type="password" class="form-control {{ $errors->has('password') ? ' is-invalid' : '' }}"
                       placeholder="密 码" name="password" required>
                <span class="glyphicon glyphicon-lock form-control-feedback"></span>

                @if ($errors->has('password'))
                    <span class="invalid-feedback">
                        <strong class="text-danger">{{ $errors->first('password') }}</strong>
                    </span>
                @endif
            </div>

            <div class="row">
                <div class="col-xs-8">
                    <div class="checkbox icheck">
                        <label>
                            <input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> 记住我
                        </label>
                    </div>
                </div>

                <!-- /.col -->
                <div class="col-xs-4">
                    <button type="submit" class="btn btn-primary btn-block btn-flat">登 录</button>
                </div>
                <!-- /.col -->
            </div>
        </form>

创建后台home控制器,运行:

php artisan make:controller Admin/Home/HomeController

编写index方法返回视图

<?php

namespace App\Http\Controllers\Admin\Home;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class HomeController extends Controller
{
    //
    public function index()
    {
        return view(admin_view_base_path('home.index'));
    }

}

若仅作登录之后跳转测试,home视图中保留注销按钮即可,例:
home.blade

<div class="pull-right">
    <a class="btn btn-default btn-flat" href="/admin/logout"
       onclick="event.preventDefault();
                         document.getElementById('logout-form').submit();">
        {{ __('注 销') }}
    </a>
</div>

<form id="logout-form" class="hide" action="{{ admin_base_path('logout') }}" method="POST" style="display: none;">
    @csrf
</form>

编辑配置文件config.admin.php,加入以下配置:

'route' => [
    'prefix' => 'admin',

    'namespace' => 'App\\Http\\Controllers\\Admin',

    'middleware' => ['web', 'admin'],
],

编写路由文件routes/admin.php

<?php

use Illuminate\Routing\Router

Route::group([
    'prefix'        => config('admin.route.prefix'),
    'namespace'     => config('admin.route.namespace'),
    'middleware'    => config('admin.route.middleware'),
], function (Router $router) {
    $router->get('/', 'Home\HomeController@index');
    $router->get('login', 'Auth\LoginController@getLoginForm');
    $router->post('login', 'Auth\LoginController@postLogin');
    $router->post('logout', 'Auth\LoginController@postLogout');
});

数据表迁移与填充: 修改database/seeds/DatabaseSeeder

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
        DB::table('administrators')->insert(
            [
                'login_name' => 'admin',
                'display_name' => '超级管理员',
                'password' => bcrypt('123456'),
                'created_at' => date('Y-m-d H:i:s', time()),
                'updated_at' => date('Y-m-d H:i:s', time()),
            ]
        );
    }
}

运行:

php artisan migrate //数据表迁移
php artisan db:seed //数据填充

如果前台使用了laravel框架用户认证的话,需要重写框架生成的LoginControllerlogout方法。防止前台用户注销的时候清除后台用户的session。(ps:框架自带用户认证在注销时会清空所有session)

/**
 * 重写前台注销操作
 * @param Request $request
 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
 */
public function logout(Request $request)
{
    $this->guard()->logout();

    $request->session()->forget('uri.intented');

    return redirect('/');
}

至此,后台用户登录全部完成。enjoy it!


kaihongChan
29 声望2 粉丝

混迹行业的程序猿